package cn.edu.zut.mock;

import cn.edu.zut.bean.Driver;
import com.github.javafaker.Faker;

import java.sql.*;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class DriverDataGenerator {

    private static final String DB_URL = "jdbc:mysql://hadoop102:3306/driver?allowPublicKeyRetrieval=true&useSSL=false&requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;

    public static void main(String[] args) {
        int count = 100; // 默认生成10条数据
        LocalDateTime startTime = LocalDateTime.now().minusDays(1); // 默认从1天前开始
        LocalDateTime endTime = LocalDateTime.now(); // 到现在为止

        // 解析命令行参数
        if (args.length >= 1) {
            count = Integer.parseInt(args[0]);
        }
        if (args.length >= 4) {
            startTime = LocalDateTime.of(
                    Integer.parseInt(args[1]), // 年
                    Integer.parseInt(args[2]), // 月
                    Integer.parseInt(args[3]), // 日
                    0, 0); // 时间设为 00:00
        }
        if (args.length >= 7) {
            endTime = LocalDateTime.of(
                    Integer.parseInt(args[4]), // 年
                    Integer.parseInt(args[5]), // 月
                    Integer.parseInt(args[6]), // 日
                    23, 59); // 时间设为 23:59
        }

        generateData(count, startTime, endTime);
    }

    public static void generateData(int count, LocalDateTime startTime, LocalDateTime endTime) {
        Faker faker = new Faker(Locale.CHINA);
        List<Driver> drivers = new ArrayList<>();

        for (long i = 1; i <= count; i++) {
            LocalDateTime createTime = randomLocalDateTime(faker, startTime, endTime);
            LocalDateTime updateTime = randomLocalDateTime(faker,
                    createTime,
                    endTime.isAfter(LocalDateTime.now()) ? LocalDateTime.now() : endTime);

            Driver driver = Driver.builder()
                    .driver_id(String.valueOf(i))
                    .driver_name(generateChineseName(faker))
                    .driver_phone(generateValidPhoneNumber(faker))
                    .driver_gender(generateRandomGender(faker))
                    .driver_age(faker.number().numberBetween(22, 60))
                    .driver_car_number(generateValidCarNumber(faker))
                    .driver_car_type(generateRandomCarType(faker))
                    .driver_mark(String.valueOf(faker.number().randomDouble(2, 3, 5)))
                    .total_orders(generateRandomTotalOrders(faker))
                    .createTime(createTime)
                    .updateTime(updateTime)
                    .build();
            drivers.add(driver);
        }

        // 插入数据库
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            conn.setAutoCommit(false);
            String sql = "INSERT INTO driver (" +
                    "driver_id, driver_name, driver_phone, driver_gender, driver_age, " +
                    "driver_car_number, driver_car_type, driver_mark, total_orders, create_time, update_time" +
                    ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                for (int i = 0; i < drivers.size(); i++) {
                    Driver driver = drivers.get(i);
                    pstmt.setString(1, driver.getDriver_id());
                    pstmt.setString(2, driver.getDriver_name());
                    pstmt.setString(3, driver.getDriver_phone());
                    pstmt.setString(4, driver.getDriver_gender());
                    pstmt.setInt(5, driver.getDriver_age());
                    pstmt.setString(6, driver.getDriver_car_number());
                    pstmt.setString(7, driver.getDriver_car_type());
                    pstmt.setString(8, driver.getDriver_mark());
                    pstmt.setString(9, driver.getTotal_orders());
                    pstmt.setTimestamp(10, Timestamp.valueOf(driver.getCreateTime()));
                    pstmt.setTimestamp(11, Timestamp.valueOf(driver.getUpdateTime()));
                    pstmt.addBatch();

                    if ((i + 1) % BATCH_SIZE == 0) {
                        pstmt.executeBatch();
                    }
                }
                pstmt.executeBatch();
                conn.commit();
                System.out.println("成功插入" + count + "条司机数据");
            } catch (SQLException e) {
                conn.rollback();
                e.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 随机生成性别：男 / 女 / 保密
     */
    public static String generateRandomGender(Faker faker) {
        String[] genders = {"男", "女"};
        return genders[faker.random().nextInt(genders.length)];
    }

    private static String generateValidPhoneNumber(Faker faker) {
        String[] prefixes = {"130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
                "145", "147", "150", "151", "152", "153", "155", "156", "157", "158", "159",
                "170", "171", "172", "173", "175", "176", "177", "178", "180", "181", "182",
                "183", "184", "185", "186", "187", "188", "189", "198", "199"};
        String prefix = prefixes[faker.random().nextInt(prefixes.length)];
        String suffix = String.format("%08d", faker.random().nextInt(100000000));
        return prefix + suffix;
    }

    /**
     * 生成符合中文姓名规则的姓名（姓 + 名），总长度为 2 或 3 个字
     */
    public static String generateChineseName(Faker faker) {
        String[] surnames = {"张", "王", "李", "赵", "刘", "陈", "杨", "黄", "周", "吴", "徐", "孙", "马", "朱", "胡",
                "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许"};

        String[] firstNames = {"婷", "杰", "琳", "帅", "芳", "俊", "艳", "超", "霞", "凯", "慧", "鹏", "蓉", "昊", "颖", "梦琪", "嘉欣", "宇航", "雨婷", "子豪", "欣怡", "俊杰", "佳琪", "浩然", "梓萱", "明轩", "诗雨", "博文", "雨欣", "泽宇", "淑芬", "建伟", "红梅", "建国", "桂兰", "志强", "丽娟", "建军", "秀莲", "卫国", "美华", "立强", "春燕", "德芳", "玉婷", "若曦", "语萱", "书瑶", "子墨", "诗涵", "雨晨", "欣然", "思远"};

        String surname = surnames[faker.random().nextInt(surnames.length)];
        String firstName = firstNames[faker.random().nextInt(firstNames.length)];

        return surname + firstName;
    }

    private static String generateValidCarNumber(Faker faker) {
        String[] provinceAbbreviations = {"京", "津", "沪", "渝", "冀", "豫", "云", "辽", "黑", "湘", "皖", "鲁", "新", "苏", "浙", "赣", "鄂", "桂", "甘", "晋", "蒙", "陕", "吉", "闽", "贵", "粤", "青", "藏", "琼"};
        String[] letters = {"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
        String province = provinceAbbreviations[faker.random().nextInt(provinceAbbreviations.length)];
        String letter = letters[faker.random().nextInt(letters.length)];
        String number = String.format("%05d", faker.random().nextInt(100000));
        return province + letter + number;
    }

    private static String generateRandomCarType(Faker faker) {
        String[] carTypes = {"SUV", "MPV", "轿车", "面包车", "商务车", "皮卡"};
        return carTypes[faker.random().nextInt(carTypes.length)];
    }
    private static String generateRandomTotalOrders(Faker faker) {
        return String.valueOf(faker.random().nextInt(1000));
    }


    private static LocalDateTime randomLocalDateTime(Faker faker, LocalDateTime start, LocalDateTime end) {
        ZonedDateTime startZoned = start.atZone(ZoneId.systemDefault());
        ZonedDateTime endZoned = end.atZone(ZoneId.systemDefault());

        long startEpoch = startZoned.toInstant().toEpochMilli();
        long endEpoch = endZoned.toInstant().toEpochMilli();

        long randomEpoch = faker.date().between(new java.util.Date(startEpoch), new java.util.Date(endEpoch)).getTime();

        return LocalDateTime.ofInstant(
                java.time.Instant.ofEpochMilli(randomEpoch),
                ZoneId.systemDefault()
        );
    }
}
